/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package controller;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.border.Border;
import model.Checkerboard;
import error.ErrorDialog;
import java.awt.Cursor;
import java.awt.Image;
import java.awt.Point;
import java.awt.Toolkit;
import java.util.ArrayList;
import view.UserOption;

/**
 *
 * @author Robert
 */
public class cSquare extends JPanel implements MouseListener, MouseMotionListener {

    private int row;            //Number of the selected line x
    private int column;         //Number of the selected column y
    private int sizeSquare;     //Size of the square
    private int oldX,           //Previous coord x
                oldY;           //Previous coord x

    private boolean remooveListener = false;   // DOn't put listerner on light square

    private JPanel grid;
    private cCheckerboard checkerboard;
    private UserOption userOption;

    // Define the piece's color. Used in function paintComponent
    private int pieceColor;
    public static final int P1Color = 1;        // Black
    public static final int P2Color = 2;        // Red
    public static final int darkSquare = 3;


    public cSquare(int c,int r, int size, JPanel g, cCheckerboard cb, UserOption uOption) {
        row = r;
        column = c;
        sizeSquare = size;
        grid = g;
        checkerboard = cb;
        userOption = uOption;

        pieceColor = 0;

        addMouseListener(this);
        addMouseMotionListener(this);
    }

    public void removeListerner(boolean remove) {
        if(remove == true)
        {
            this.removeMouseListener(this);
            this.removeMouseMotionListener(this);
        }
    }

    /************************
     *  GET & SET FUNCTIONS *
     ************************/
    public int getRow() {return row;}
    public int getColumn() {return column;}
    public int getPieceColor() {return pieceColor;}
    public void setPieceColor(int pieceColor) {this.pieceColor = pieceColor;}



    /************************
     *    EVENT FUNCTIONS   *
     ************************/
    /* Récupération et conversion des coordonnéess lors d'un clic */
    public void mousePressed(MouseEvent e) {
        // On récupère les coordonnées sur la frame
        oldX = e.getXOnScreen()-4;
        oldY = e.getYOnScreen()-27;
        //System.out.println("Mouse pressed on " + oldX + ";"+oldY);

        // On convertit ses coordonnées par la taille d'une case pour obtenir les coordonnées du tableau de cases : cCheckerboard
        column = oldX/sizeSquare;
        row = oldY/sizeSquare;
        if(checkerboard.getCheckerboard().getPlayer() == 1 )    // Joueur 1
            play(1);
        else
            play(2);
    }

    /**
     * Condition : a pawn/queen is selected
     * after checking, if player can move to the selected square, update checkerboard.
     *                 else cancel move
     */
    public void mouseReleased(MouseEvent e) {
        /* Get location */
        oldX = e.getXOnScreen()-4;
        oldY = e.getYOnScreen()-27;
        row = oldY/sizeSquare;
        column = oldX/sizeSquare;
        System.out.println("Release on square : " + column + ";" + row);
        //this.revalidate(); /* EDIT A UTILISER EN CAS D'ERREUR DE LA PART DU JOUEUR */
    }

    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
    public void mouseDragged(MouseEvent e) {}
    public void mouseMoved(MouseEvent e) {}
    public void mouseClicked(MouseEvent e) {}


    /************************
     *     PLAY & CHECK     *
     ************************/
    /**
     * @param noPlayer : Value is 1 for player 1
     *                   Value is 2 for player 2
     */
    public void play(int noPlayer){
        int pawn = 0;
        int queen =0;
        if (noPlayer == 1)
        {
            pawn = Checkerboard.P1_PAWN;
            queen =Checkerboard.P1_QUEEN;
        }
        else if(noPlayer == 2)
        {
            pawn = Checkerboard.P2_PAWN;
            queen =Checkerboard.P2_QUEEN;
        }

        if(checkerboard.getCheckerboard().getIsSelected() == false) // Aucune pièce n'a été selectionnée
            {
                // Il faut que la pièce appartiennent au joueur
                if(checkerboard.getCheckerboard().getSquare(column, row).getIsOccupied() == pawn
                        || checkerboard.getCheckerboard().getSquare(column, row).getIsOccupied() == queen)
                {
                    // update checkerboard : A piece is selected
                    int squareId = checkerboard.getCheckerboard().getSquare(column, row).getIdSquare();
                    checkerboard.getCheckerboard().setIdSelectedSquare(squareId);
                    checkerboard.getCheckerboard().setIsSelected(true);

                    // On change la couleur du panel selectionné
                    Border borderColor = BorderFactory.createLineBorder(Color.CYAN, 3);
                    this.setBorder(borderColor);
                    System.out.println("Click on " + column + ";" + row +" = " + squareId);

                    // Change form of the cursor
                    if(noPlayer == 1)
                        this.changeCursorForm(1);
                    else if(noPlayer == 2)
                        this.changeCursorForm(2);
                }
                else
                    System.out.println("Error");
            }
            else    // Pièce déjà selectionné : Déplacement à faire
            {
                // EDIT : Fonction pour récupérer les cases selectionnables
                int oldRow, oldColumn;
                int previousSquareId  = checkerboard.getCheckerboard().getIdSelectedSquare();
                cSquare previousSquare = (cSquare) grid.getComponent(previousSquareId);
                oldRow = previousSquare.getRow();
                oldColumn = previousSquare.getColumn();

                if(oldRow == row && oldColumn == column)    // Selection de la même pièce à nouveau ==> On la déselectionne
                {
                    checkerboard.getCheckerboard().setIsSelected(false);
                    Border borderColor = BorderFactory.createLineBorder(Color.green, 2);
                    previousSquare.setBorder(borderColor);

                    // Clear cursor form
                    this.changeCursorForm(0);
                }
                else
                {
                    System.out.println("coord " + oldColumn + ";"+oldRow + "   &   "+ column +";"+row);
                    if(cMove.move(checkerboard, oldColumn, oldRow, column, row) == false) // Dans le cas où on ne peut pas bouger
                    {
                        /**EDIT Pour le jump, mettre message spécial aussi **/
                         ErrorDialog error = new ErrorDialog("Déplacement non autorisé");
                    }
                    else                                                                // Cas où on peut se déplacer
                    {
                        // On déplace la pièce à sa nouvelle position
                        int squareId = checkerboard.getCheckerboard().getSquare(column, row).getIdSquare();
                        cSquare square = (cSquare) grid.getComponent(squareId);
                        if(noPlayer ==1)
                            square.setPieceColor(cSquare.P1Color);
                        else if (noPlayer ==2)
                            square.setPieceColor(cSquare.P2Color);
                        square.setBackground(Color.WHITE);              // Permet le dessin


                        // On nettoie l'ancienne case
                        previousSquare.setPieceColor(cSquare.darkSquare);
                        previousSquare.setBackground(Color.WHITE);              // Permet le dessin

                        Border borderColor = BorderFactory.createLineBorder(Color.BLUE, 1);
                        previousSquare.setBorder(borderColor);

                        // update checkerboard : End of turn
                        checkerboard.getCheckerboard().setIdSelectedSquare(squareId);
                        checkerboard.getCheckerboard().setIsSelected(false);
                        //Move.move(checkerboard.getCheckerboard(), oldColumn, oldRow, column, row);

                        // Clear cursor form
                        this.changeCursorForm(0);

                        // Clear playablePieces and effect
                        this.clearPlayablePieces();


                        /** END OF TURN : EDIT IF JUMP POSSIBLE **/
                        if(checkerboard.getCheckerboard().getPlayer() == 1)
                        {
                            //checkPlayablePieces(2);
                            //displayPlayablePieces(2);
                            checkerboard.getCheckerboard().setPlayer(2);

                        }
                        else if(checkerboard.getCheckerboard().getPlayer() == 2)
                        {
                            //checkPlayablePieces(1);
                            //displayPlayablePieces(1);
                            checkerboard.getCheckerboard().setPlayer(1);

                        }

                        /* Modification on UserOption */
                          String player = Integer.toString(checkerboard.getCheckerboard().getPlayer());
                          userOption.setLabelPlayer(player);
                          String nbPieceP1 = Integer.toString(checkerboard.getCheckerboard().getNbPiecesPlayer1());
                          userOption.setLabelNbPieceLeftP1(nbPieceP1);
                          String nbPieceP2 = Integer.toString(checkerboard.getCheckerboard().getNbPiecesPlayer2());
                          userOption.setLabelNbPieceLeftP1(nbPieceP2);


                    }
                }
            }
    }

    /**
     * Before the player turn : Check witch pieces are playable
     *  - If no pieces can jump : show all pieces who can only moves
     *  - If one or many pieces can jump :
     *          --> don't show those who can only moves
     *          --> Show thoses who can jump the most
     * For more information: check draught's rules
     * @param noPlayer : Value is 1 for player 1
     *                   Value is 2 for player 2
     */
    public void checkPlayablePieces(int noPlayer)
    {
        int i, j;
        int pawn = 0;
        int queen =0;
        ArrayList <Move> liste;
        Move move;
        if (noPlayer == 1)
        {
            pawn = Checkerboard.P1_PAWN;
            queen =Checkerboard.P1_QUEEN;
        }
        else if(noPlayer == 2)
        {
            pawn = Checkerboard.P2_PAWN;
            queen =Checkerboard.P2_QUEEN;
        }
        for(j=0; j<10;j++)
        {
             for(i=0; i<10;i++)
             {
                // Check if pieces belongs to the Player
                if(checkerboard.getCheckerboard().getSquare(i, j).getIsOccupied() == pawn
                    || checkerboard.getCheckerboard().getSquare(i, j).getIsOccupied() == queen)
                {

                    liste = Move.getMoves(checkerboard.getCheckerboard(), i, j);
                    for (int k = 0; k < liste.size(); k++) {
                        move = liste.get(k);
                        move.getDestX();
                        move.getDestY();
                        //System.out.println("Pour "+i +";"+j +" -> Dest = " + move.getDestX()+ ";"+move.getDestY());;
                    }
                    //this.goSouthEast(i, j, pawn);
                    this.goSouthWest(i, j, pawn);
                    //this.goNorthEast(i, j, pawn);
                    //this.goSouthWest(i, j, pawn);
                }
             }
        }
    }


    /**
     * Check if the piece can move/jump
     * if it can, it may be playable (but have to check the best jump)
     *  N
     *W + E
     *  S
     * @param rowSquare : coord x
     * @param columnSquare : coord y
     * @params type : if pawn : value is 1 or 3
     *                 if queen: value is 2 or 4
     */
    public void goSouthWest(int columnSquare, int rowSquare, int type){
        int nextRow = rowSquare+1;
        int nextColumn = columnSquare-1;
        if(nextRow != 10 && nextColumn != -1)
        {
            if(type == Checkerboard.P1_PAWN || type == Checkerboard.P2_PAWN )
            {
                // can move to south west
                if(cMove.move(checkerboard, columnSquare, rowSquare, nextColumn, nextRow) == true)
                {
                    int id = checkerboard.getCheckerboard().getSquare(columnSquare, rowSquare).getIdSquare();
                    System.out.println("id ==> " + id);
                    checkerboard.getCheckerboard().setTabPlayablePieces(id, checkerboard.getCheckerboard().getNbPlayablePieces());
                }
            }
        }
    }

    public void goSouthEast(int columnSquare, int rowSquare, int type){
       int nextRow = rowSquare+1;
        int nextColumn = columnSquare+1;

        if(nextRow != 10 && nextColumn != 10)
        {
            if(type == Checkerboard.P1_PAWN || type == Checkerboard.P2_PAWN )
            {
                // can move to south west
                if(cMove.move(checkerboard, columnSquare, rowSquare, nextColumn, nextRow) == true)
                {
                    int id = checkerboard.getCheckerboard().getSquare(columnSquare, rowSquare).getIdSquare();
                    checkerboard.getCheckerboard().setTabPlayablePieces(id, checkerboard.getCheckerboard().getNbPlayablePieces());
                }
            }
        }
    }

     public void goNorthWest(int columnSquare, int rowSquare, int type){
       int nextRow = rowSquare-1;
        int nextColumn = columnSquare-1;

        if(nextRow != -1 && nextColumn != -1)
        {
            if(type == Checkerboard.P1_PAWN || type == Checkerboard.P2_PAWN )
            {
                // can move to south west
                if(cMove.move(checkerboard, columnSquare, rowSquare, nextColumn, nextRow) == true)
                {
                    int id = checkerboard.getCheckerboard().getSquare(columnSquare, rowSquare).getIdSquare();
                    checkerboard.getCheckerboard().setTabPlayablePieces(id, checkerboard.getCheckerboard().getNbPlayablePieces());
                }
            }
        }
    }

    public void goNorthEast(int columnSquare, int rowSquare, int type){
       int nextRow = rowSquare-1;
        int nextColumn = columnSquare+1;

        if(nextRow != -1 && nextColumn != 10)
        {
            if(type == Checkerboard.P1_PAWN || type == Checkerboard.P2_PAWN )
            {
                // can move to south west
                if(cMove.move(checkerboard, columnSquare, rowSquare, nextColumn, nextRow) == true)
                {
                    int id = checkerboard.getCheckerboard().getSquare(columnSquare, rowSquare).getIdSquare();
                    checkerboard.getCheckerboard().setTabPlayablePieces(id, checkerboard.getCheckerboard().getNbPlayablePieces());
                }
            }
        }
    }


     /***********************
     *      CHANGE VIEW     *
     ************************/

    /**
     * The cursor will take -The form of the selected piece
     *                      -Default form if not
     * @param noPlayer :
     * If a piece is selected
     *      Value is 1 for player 1
     *      Value is 2 for player 2
     * Else
     *      Value is 0
     */
    public void changeCursorForm(int noPlayer){
        Toolkit toolkit = Toolkit.getDefaultToolkit();
        Image image;
        Cursor c = Cursor.getDefaultCursor();
        if(noPlayer == 1)
        {
            image = toolkit.getImage("../jdd/src/img/black_pawn1.png");
            c = toolkit.createCustomCursor(image , new Point(grid.getX(),grid.getY()), "img");
        }
        else if(noPlayer == 2)
        {
            image = toolkit.getImage("../jdd/src/img/red_pawn1.png");
            c = toolkit.createCustomCursor(image , new Point(grid.getX(),grid.getY()), "img");
        }

        if(noPlayer == 0)
            c = Cursor.getDefaultCursor();
        grid.setCursor (c);

    }

    /**
     * At the end of a turn :
     * - Clear border color of the playable pieces in the view
     * - Clear tabPlayablePieces for the next player
     */
    public void clearPlayablePieces()
    {
        int k;
        for(k=0; k< checkerboard.getCheckerboard().getNbPlayablePieces(); k++)
        {
            cSquare square = (cSquare) grid.getComponent(checkerboard.getCheckerboard().getValueTabPlayablePieces(k));
            if(checkerboard.getCheckerboard().getValueTabPlayablePieces(k) != -1)   // if = -1, it would be a wrong value set by default
            {
                Border borderColor = BorderFactory.createLineBorder(Color.blue, 1);
                square.setBorder(borderColor);
            }
        }
        checkerboard.clearTabPlayablePieces();
    }
    /**
     * At the beginning of a turn. After Using checkPlayablePieces()
     * Change border color the playable pieces by looking tabPlayablePieces
     * @param noPlayer : Value is 1 for player 1
     *                   Value is 2 for player 2
     */
    public void displayPlayablePieces(int noPlayer)
    {
        int k;
        /* Show all playables pieces */
        for(k=0; k< checkerboard.getCheckerboard().getNbPlayablePieces(); k++)
        {

            cSquare square = (cSquare) grid.getComponent(checkerboard.getCheckerboard().getValueTabPlayablePieces(k));
            if(checkerboard.getCheckerboard().getValueTabPlayablePieces(k) != -1)
            {
                Border borderColor = BorderFactory.createLineBorder(Color.green, 2);
                square.setBorder(borderColor);
            }
        }
    }

    /************************
     *    Drawing Methods   *
     ************************/
     @Override
    public void paintComponent(Graphics g) {
      clear(g);
      Graphics2D g2d = (Graphics2D)g;
      switch(this.pieceColor)
      {
          case 1 :  // Draw a pawn for Player 1
                drawP1Pawn(g2d);
                break;
          case 2 :  // Draw a pawn for Player 2
              drawP2Pawn(g2d);
              break;
          case 3 :  // clear dark square
              clearSquare(g2d);
              break;
          case 4 :
              drawP1Queen(g2d);
              break;
          case 5 :
              drawP2Queen(g2d);
              break;
          default:
              break;
      }
    }

    public void drawP1Pawn(Graphics2D g2d)
    {
      this.setBackground(Color.BLUE);
      g2d.setColor(Color.BLACK);
      g2d.fillOval(5, 5, 40, 40);
    }

    public void drawP1Queen(Graphics2D g2d)
    {
      this.setBackground(Color.BLUE);
      g2d.setColor(Color.BLACK);
      g2d.fillOval(5, 5, 40, 40);
      g2d.setColor(Color.white);
      g2d.drawOval(20, 20, 10, 10);

    }

    public void drawP2Pawn(Graphics2D g2d)
    {
      this.setBackground(Color.BLUE);
      g2d.setColor(Color.RED);
      g2d.fillOval(5, 5, 40, 40);
    }

    public void drawP2Queen(Graphics2D g2d)
    {
      this.setBackground(Color.BLUE);
      g2d.setColor(Color.RED);
      g2d.fillOval(5, 5, 40, 40);
      g2d.setColor(Color.white);
      g2d.drawOval(20, 20, 10, 10);
    }

    public void clearSquare(Graphics2D g2d)
    {
      g2d.clearRect(sizeSquare, sizeSquare, oldX, oldY);
      this.setBackground(Color.BLUE);
    }
    protected void clear(Graphics g) {super.paintComponent(g);}
}

